package repository

import (
	"boy-go/modules/system/aspect"
	"boy-go/modules/system/model"
	"boy-go/modules/system/vo"
	"boy-go/pkg/db"
	"boy-go/pkg/request"
	"fmt"
	"gorm.io/gorm"
)

var (
	_selectDeptVo = "d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag, d.create_by, d.create_time "
)

type SysDeptRepository struct {
	DB *gorm.DB
}

func NewSysDeptRepository() *SysDeptRepository {
	return &SysDeptRepository{
		DB: db.GetMasterDB(),
	}
}
func (r *SysDeptRepository) GetById(deptId int64) (*model.SysDept, error) {
	db := r.DB
	m := &model.SysDept{}
	err := db.Model(&model.SysDept{}).Where("dept_id = ?", deptId).First(m).Error
	if err != nil {
		return nil, err
	}
	return m, nil
}
func (r *SysDeptRepository) SelectSysDeptByIds(ids []*int64) ([]*model.SysDept, error) {
	tx := r.DB.Model(&model.SysDept{})
	list := make([]*model.SysDept, 0)
	err := tx.Where("dept_id in (?)", ids).Find(&list).Error
	return list, err
}
func (r *SysDeptRepository) SelectDeptListByRoleId(roleId int64, deptCheckStrictly bool) []*int64 {
	sql := "select d.dept_id from sys_dept d left join sys_role_dept rd on d.dept_id = rd.dept_id"
	sql += fmt.Sprintf(" where rd.role_id = %d", roleId)
	if deptCheckStrictly {
		sql += fmt.Sprintf(" and d.dept_id not in (select d.parent_id from sys_dept d inner join sys_role_dept rd on d.dept_id = rd.dept_id and rd.role_id = %d)", roleId)
	}
	list := make([]*int64, 0)
	err := r.DB.Raw(sql).Find(&list).Error
	if err != nil {
		return nil
	}
	return list
}
func (r *SysDeptRepository) List(query *vo.QuerySysDeptReq, pageReq *request.PageRequest) ([]*model.SysDept, int64, error) {
	tx := r.DB.Model(&model.SysDept{})
	if query != nil {
		if query.ParentId != nil {
			tx = tx.Where("parent_id = ?", *query.ParentId)
		}
		if query.Ancestors != nil {
			tx = tx.Where("ancestors = ?", *query.Ancestors)
		}
		if query.DeptName != nil {
			tx = tx.Where("dept_name = ?", *query.DeptName)
		}
		if query.OrderNum != nil {
			tx = tx.Where("order_num = ?", *query.OrderNum)
		}
		if query.Leader != nil {
			tx = tx.Where("leader = ?", *query.Leader)
		}
		if query.Phone != nil {
			tx = tx.Where("phone = ?", *query.Phone)
		}
		if query.Email != nil {
			tx = tx.Where("email = ?", *query.Email)
		}
		if query.Status != nil {
			tx = tx.Where("status = ?", *query.Status)
		}
		if query.DelFlag != nil {
			tx = tx.Where("del_flag = ?", *query.DelFlag)
		}
		if query.CreateBy != nil {
			tx = tx.Where("create_by = ?", *query.CreateBy)
		}
		if query.CreateTime != nil {
			tx = tx.Where("create_time = ?", *query.CreateTime)
		}
		if query.UpdateBy != nil {
			tx = tx.Where("update_by = ?", *query.UpdateBy)
		}
		if query.UpdateTime != nil {
			tx = tx.Where("update_time = ?", *query.UpdateTime)
		}
	}
	list := make([]*model.SysDept, 0)
	if pageReq != nil {
		var total int64
		if err := tx.Count(&total).Error; err != nil {
			return nil, 0, err
		}
		if total > 0 {
			tx = db.BuildPageAndOrder(tx, pageReq, "d.parent_id,d.order_num")
			tx = aspect.HandleDataScopeByDB(tx, "d", "")
			if err := tx.Select(_selectDeptVo).Table("sys_dept d").Find(&list).Error; err != nil {
				return nil, total, err
			}
		}
		return list, total, nil
	} else {
		tx = aspect.HandleDataScopeByDB(tx, "d", "")
		if err := tx.Select(_selectDeptVo).Table("sys_dept d").Order("d.parent_id,d.order_num").Find(&list).Error; err != nil {
			return nil, 0, err
		}
	}
	return list, int64(len(list)), nil
}

// Save 添加
func (r *SysDeptRepository) Save(m *model.SysDept) error {
	return r.DB.Model(&model.SysDept{}).Create(m).Error
}

// Update 更新
func (r *SysDeptRepository) Update(m *model.SysDept) error {
	return r.DB.Model(&model.SysDept{}).Where("dept_id = ?", m.DeptId).Updates(m).Error
}

// Delete 删除
func (r *SysDeptRepository) Delete(deptId int64) error {
	return r.DB.Model(&model.SysDept{}).Where("dept_id = ?", deptId).Delete(&model.SysDept{}).Error
}

// DeleteBatch 批量删除
func (r *SysDeptRepository) BatchDelete(ids []string) error {
	db := r.DB
	db = db.Where("(dept_id) IN ?", ids)
	return db.Delete(&model.SysDept{}).Error
}
